const fs = require('fs');

const { Role, utils } = require('board-game');

const extend = require('extend');
const VsCard = require('./card');
const use = require('./use');

const { game: gameConfig } = require('./config');

class VsCardRole extends Role {
    constructor(server, room, player, team, index) {
        super(server, room, player, team, index);
        this.cards = [];
        this.heap  = [];
        this.pile = [];
        this.doWait();
        this.idx = false;
        this.occupation = false;
        this.latest = false;
        this.replace = 0;
    }
    clear() {
        this.cards = [];
        this.heap = [];
        this.pile = [];
        this.idx = false;
        this.status = '';
        this.occupation = false;
        this.latest = false;
        this.replace = 0;
    }
    over(win, game) {
        return extend(true, super.over(win, game), {

        });
    }
    start() {
        this.ownHome = this.board.homes.find(home => home.group.index === this.group);
        this.targetHome = this.board.homes.find(home => home.group.index !== this.group);
        this.ownGroup = this.board.groups.find(group => group.index === this.group);
        this.targetGroup = this.board.groups.find(group => group.index !== this.group);
        this.color = this.ownGroup.option.color,
        this.heap = [...VsCard.normalCards]; //牌堆
        this.pile = []; //弃牌堆
    }
    setIndex(index) {
        this.idx = VsCard.indexCard(index);
    }
    randomChoose() {
        this.doChoose(VsCardRole.occupations[Math.floor(VsCardRole.occupations.length * Math.random())].type);
    }
    doChoose(type) {
        let occupation = VsCardRole.occupations.find(o => o.type === type);
        console.log('玩家选择了:' + type);
        this.heap.push(...VsCard.occupationCards(occupation));
        this.occupation = {
            type: occupation.type,
            name: occupation.name,
            desc: occupation.desc,
        }
    }
    hasCard(option) {
        if (option) {
            return this.cards.some(card => (!option.min || card.option.value >= option.min) && (!option.max || card.option.value <= option.max));
        } else {
            return this.cards.length > 0;
        }
    }
    resetCard(card) {
        this.heap.push(card);
    }
    addCard(index) {
        if (this.cards.length >= gameConfig.card.maxCount) return false;
        if (!this.heap.length) {
            this.doShuffle();
        }
        let heapIndex = Math.floor(this.heap.length * Math.random());
        let card = this.heap[heapIndex];
        if (typeof index === 'undefined') {
            this.cards.push(card);
        } else {
            this.cards.splice(index, 0, card);
        }
        this.heap.splice(heapIndex, 1);
        return true;
    }
    removeCard(index) {
        if (this.hasCard()) {
            if (typeof index === 'undefined') {
                index = Math.floor(this.cards.length * Math.random());
            } else if (typeof index === 'object') {
                let option = index;
                let matchCards = this.cards.filter(card => (!option.min || card.option.value >= option.min) && (!option.max || card.option.value <= option.max));
                let card = matchCards[Math.floor(matchCards.length * Math.random())];
                index = this.cards.indexOf(card);
            }
            if (index !== -1) {
                let card = this.cards[index];
                this.cards.splice(index, 1);
                this.doFold(card);
                return card;
            }
        }
    }
    doShuffle() {
        while (this.pile.length) {
            let index = Math.floor(this.pile.length * Math.random());
            this.heap.push(this.pile[index]);
            this.pile.splice(index, 1);
        }
    }
    doFold(card) {
        this.pile.push(card);
    }
    doPlayCard({ cardIndex, targets }) {
        if (this.isPlay()) {
            if (cardIndex < this.cards.length) {
                let card = this.cards[cardIndex];
                this.cards.splice(cardIndex, 1);
                this.status = 'used';

                this.board.useCard(this, card, targets);
            }
        }
    }
    doReplace({ cardIndex }) {
        if (this.replace < gameConfig.card.replaceCount) {
            let card = this.cards[cardIndex];
            this.cards.splice(cardIndex, 1);
            this.heap.push(card);
            this.addCard(cardIndex);
            this.replace++;
        }
    }
    doCancelReplace() {
        this.replace = gameConfig.card.replaceCount;
    }
    doPass() {
        if (this.isPlay()) {
            this.status = 'pass';
            this.board.nextTurn();
        }
    }
    isPass() {
        return this.status === 'pass';
    }
    doPlay() {
        this.status = 'play';
    }
    doWait() {
        this.replace = 0;
        this.status = 'none';
    }
    isWait() {
        return this.status === 'none';
    }
    isPlay() {
        return this.status === 'play';
    }
    get data() {
        return extend(true, super.data,  {
            cards: utils.asObject(this.cards.map(card => card.data)),
            idx: this.idx && this.idx.data || false,
            replace: this.replace,
        });
    }
    get summary() {
        return extend(true, super.summary, {
            color: this.color || '',
            cardCount: this.cards.length,
            heapCount: this.heap && this.heap.length || 0,
            pileCount: this.pile && this.pile.length || 0,
            status: this.status || '',
            occupation: this.occupation,
            latest: use.asData(this.latest),
        })
    }
}

VsCardRole.occupations = [];

for (let file of fs.readdirSync('./occupations')) {
    if (file.endsWith('.js')) {
        VsCardRole.occupations.push(require('./occupations/' + file));
    }
}

console.log('已支持职业(' + VsCardRole.occupations.length + '):' + VsCardRole.occupations.map(o => o.name).join(","));

module.exports = VsCardRole;